package com.simple.common.entity.controller;

import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import javax.validation.ConstraintViolation;
import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 提供controller层基础方法
 * @author yasud
 * @date 2020年09月04日 11:07
 * @description
 */
public class BaseController {

    @Autowired
    LocalValidatorFactoryBean validatorFactoryBean;

    /**
     * 校验
     * @param o
     */
    protected void valid(Object o) {
        Preconditions.checkNotNull(o, "参数非空");
        Set<ConstraintViolation<Object>> validate = validatorFactoryBean.validate(o);
        for (ConstraintViolation<Object> objectConstraintViolation : validate) {
            Throwables.throwIfUnchecked(new RuntimeException(objectConstraintViolation.getMessage()));
        }
    }

    @SneakyThrows
    protected void validCheck(Object obj) {
        Class<?> aClass = obj.getClass();
        List<Field> allFieldsList = FieldUtils.getAllFieldsList(aClass);
        List<Field> collect = allFieldsList.stream().filter(field -> Objects.nonNull(field.getAnnotation(Check.class))).collect(Collectors.toList());
        List<Object> vals = Lists.newArrayList();
        for (Field field : collect) {
            field.setAccessible(true);
            Object o = field.get(obj);
            if (o instanceof Collection) {
                Collection collection = (Collection)o;
                collection.forEach(o1 -> {
                    valid(o1);
                    vals.add(o1);
                });
            }
            else {
                valid(o);
                vals.add(o);
            }
        }
        if (CollectionUtils.isNotEmpty(vals)) {
            for (Object val : vals) {
                validCheck(val);
            }
        }
    }

    /**
     * 提供一个注解完成来方便完成参数内部检查
     */
    @Documented
    @Inherited
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Check {

        String value() default "";
    }
}
